%{

open Ast;;
open Subs;;
open ToBePrinted;;

(* let compt_tab= Hastbl.create 97;; *)

%}

%token LPAREN RPAREN RCURLY LCURLY
%token EQUAL COMMA EOF
%token <string> INCLUDE
%token <string> NAME
%token <bool> BOOL
%token FOR
%token <int> ENTIER
%token PRINT PRINTADDRRAM PRINTADDRROM

%start program
%type <Ast.expAst> program

%%

/** Tools **/
%inline slist(S, x)        : l=separated_list(S, x)                    {l}
%inline snlist(S, x)       : l=separated_nonempty_list(S, x)           {l}
%inline tuple(x)           : LPAREN t=slist(COMMA,x) RPAREN { t }


program:
  | i=list(inc) l=list(bloc) EOF         {Program( i,l )}

bloc:
  | n=NAME entrees=tuple(NAME) EQUAL sorties=tuple(NAME) 
    LCURLY
		affectations=list(affectation)
                option(print)
		option(printAddrRam)
		option(printAddrRom)
    RCURLY 
    { Bloc( n,entrees,sorties,affectations ) }

affectation:
  | dest=NAME EQUAL source=valeur          { Affectation( [dest],[source] ) }
  | dest=tuple(NAME) EQUAL source=tuple(valeur) {Affectation( dest, source)} 
  | dest=tuple(NAME) EQUAL source=valeur {Affectation(dest,[source])}
  | FOR LPAREN i=NAME COMMA d=ENTIER COMMA f=ENTIER RPAREN 
      LCURLY 
        s=list(affectation) 
      RCURLY
    {ListAffectation(Subs.iter(d,f,i,s))}

print:
  | PRINT l=tuple(NAME)  {List.iter (fun x-> Hashtbl.add toBePrinted x () ) l}

printAddrRam:
  | PRINTADDRRAM l=tuple(ENTIER)  {List.iter (fun x-> Hashtbl.add addrToPrintRam x () ) l}

printAddrRom:
  | PRINTADDRROM l=tuple(ENTIER)  {List.iter (fun x-> Hashtbl.add addrToPrintRom x () ) l}

valeur:
  | l=literal               { l }
  | n=NAME t=tuple(valeur)    { Appel( n,t ) }
  
literal: 
  | n=NAME        { Variable( n ) }
  | b=BOOL        { Value( b ) }

inc:
  | n=INCLUDE { Include( n ) }




%%
